package com.csair.seam.infrastructure.log;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;

import com.alibaba.fastjson.JSON;
import com.csair.seam.domain.model.entity.Visits;
import com.csair.seam.infrastructure.sso.CustomSsoActor;
import com.csair.seam.infrastructure.utils.DateHelper;
import com.csair.seam.infrastructure.utils.JwtUtil;
import com.csair.seam.infrastructure.utils.WebUtil;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Aspect
@Component
public class LogAspect {
	@Autowired
	private ApplicationContext applicationContext;
	
	@After("@annotation(logOperation)")
	public void logForOperation(LogOperation logOperation) {
		HttpServletRequest request = getRequest();
		
		LogOptInfo optInfo = new LogOptInfo();
		optInfo.setOptName(logOperation.bizName());
		optInfo.setOptTime(DateHelper.getCurrentDateTimeStr());
		optInfo.setIp(WebUtil.getIpAddress(request));
		
		String uri = request.getRequestURI();
		if(uri.contains("/mobile")) {
			optInfo.setOptUser(JwtUtil.getAccount(request));
		}else {
			Object account = request.getSession().getAttribute(CustomSsoActor.SESSION_KEY_ACCOUNT);
			optInfo.setOptUser(String.valueOf(account));
		}
		
		//请求参数
		Map<String, String> rtnMap = converMap(request.getParameterMap());
		optInfo.setOptParams(rtnMap);
		
		log.info("【用户操作】：{}",JSON.toJSONString(optInfo));
	}
	
	public Map<String, String> converMap(Map<String, String[]> paramMap) {
		Map<String, String> rtnMap = new HashMap<String, String>();
		for (String key : paramMap.keySet()) {
			rtnMap.put(key, paramMap.get(key)[0]);
		}
		return rtnMap;
	}
	
	@Before("@annotation(visitsLog)")
	public void addVisitsLog(VisitsLog visitsLog) {
		Visits visits = initVisits();
		visits.setModuleCode(visitsLog.module().getCode());
		visits.setModuleName(visitsLog.module().getName());
		
		applicationContext.publishEvent(new VisitsLogEvent(visits));
	}
	
	private Visits initVisits() {
		HttpServletRequest request = getRequest();
		String ip = WebUtil.getIpAddress(request);
		String uri = request.getRequestURI();
		Visits visits = new Visits();
		visits.setAddress(ip);
		visits.setVisitTime(DateHelper.getCurrentDateStr());
		if(uri.contains("/mobile")) {
			visits.setUserCode(JwtUtil.getAccount(request));
		}else {
			Object account = request.getSession().getAttribute(CustomSsoActor.SESSION_KEY_ACCOUNT);
			visits.setUserCode(String.valueOf(account));
		}
		return visits;
	}
	
	private HttpServletRequest getRequest() {
		RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); 
		HttpServletRequest request = (HttpServletRequest) requestAttributes.resolveReference(RequestAttributes.REFERENCE_REQUEST);
		return request;
	}
}
